package com.wenzheng.quartz.service;

import com.wenzheng.quartz.common.*;
import com.wenzheng.quartz.common.utils.*;
import com.wenzheng.quartz.dao.*;
import com.wenzheng.quartz.domain.pojo.*;
import com.wenzheng.quartz.domain.vo.*;
import com.wenzheng.quartz.task.*;
import org.apache.commons.lang.exception.*;
import org.slf4j.*;
import org.springframework.beans.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.stereotype.*;
import org.springframework.transaction.annotation.*;
import org.springframework.util.*;

import java.util.*;

@Service
public class TaskItemService {
	private Logger log = LoggerFactory.getLogger(getClass());
	@Autowired
	private TaskItemDao dao;
	@Autowired
	private TaskManager manager;

	/**
	 * 初始化方法
	 * <br/>用于容器启动后，将数据库中的任务添加到quartz任务调度中心
	 */
	public void initTask() {
		try {
			// 从数据库查询出所有启用状态的定时任务
			List<TaskItem> list = dao.findAllByStatus(TaskItemStatusEnum.Enabled.getStatus());
			if (!CollectionUtils.isEmpty(list)) {
				// 添加到调度中心
				for (TaskItem taskItem : list) {
					manager.addJob(taskItem.getTaskName(), taskItem.getTaskClassName(), taskItem.getCron(), taskItem.getDescription());
				}
			}
			log.info("Loading task from db to quartz SUCCESS");
		}catch (Exception e) {
			log.error("TaskItemService initTask method exception-->{}", ExceptionUtils.getFullStackTrace(e));
		}
	}

	public List<TaskItem> findAll() {
		return dao.findAll();
	}

	@Transactional
	public void delete(Integer id) {
		Optional<TaskItem> optional = dao.findById(id);
		optional.ifPresent((x) -> {
			try {
				dao.deleteById(id);
				manager.deleteJob(optional.get().getTaskName());
			}catch (Exception e) {
				log.error("TaskItemService delete error with id -->{} ,exception is -->{}", id, ExceptionUtils.getFullStackTrace(e));
				throw new RuntimeException("删除任务失败", e);
			}

		});


	}

	@Transactional
	public ModelResult<Void> add(AddTaskVo vo) {
		try {
			ModelResult<Void> result = new ModelResult<>();
			TaskItem taskItem = new TaskItem();
			BeanUtils.copyProperties(vo, taskItem);
			taskItem.setStatus(TaskItemStatusEnum.Enabled.getStatus());
			dao.save(taskItem);
			manager.addJob(taskItem.getTaskName(), taskItem.getTaskClassName(), taskItem.getCron(), taskItem.getDescription());
			return result;
		}catch (Exception e) {
			log.error("TaskItemServiceve add error with vo-->{} ,exception is -->{}", JsonUtils.object2Json(vo), ExceptionUtils.getFullStackTrace(e));
			throw new RuntimeException("添加任务失败", e);
		}

	}

	@Transactional
	public void updateStatus(int id, int status) {
		Optional<TaskItem> optional = dao.findById(id);
		optional.ifPresent((x) -> {
			try {
				x.setStatus(status);
				dao.save(x);
				if (status == TaskItemStatusEnum.Enabled.getStatus()) {
					// 如果启用就新增任务
					manager.addJob(x.getTaskName(), x.getTaskClassName(), x.getCron(), x.getDescription());
				}else {
					// 禁用就删除任务，不能用暂停，容易出bug
					manager.deleteJob(x.getTaskName());
				}
			}catch (Exception e) {
				log.error("TaskItemServiceve updateStatus exception is -->{}", ExceptionUtils.getFullStackTrace(e));
				throw new RuntimeException("修改任务状态失败", e);
			}
		});

	}

	public TaskItem findById(int id) {
		return dao.findById(id).get();
	}


	@Transactional
	public void update(UpdateTaskVo vo) {
		try {
			TaskItem taskItem = dao.findById(vo.getId()).get();
			BeanUtils.copyProperties(vo, taskItem);
			dao.save(taskItem);
			// 处于启用状态的任务需要更新cron
			if (taskItem.getStatus().equals(TaskItemStatusEnum.Enabled.getStatus())) {
				manager.updateJobTime(taskItem.getTaskName(), taskItem.getCron(), vo.getDescription());
			}
		}catch (Exception e) {
			log.error("TaskItemServiceve update exception, vo -->{} exception is -->{}", JsonUtils.object2Json(vo), ExceptionUtils.getFullStackTrace(e));
			throw new RuntimeException("更新任务异常", e);
		}
	}


}
